namespace CRM_Perf_BenchMark
{
    using System;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.TestTools.WebTesting;
    using System.Net;
    using System.Text;
    using System.Xml;
    
    /// <summary>
    ///1. Start point Marketing Tab
    ///2. Select Marketing Lists 
    ///3. Select new button
    ///4. Enter data in form (name, member type Account)
    ///5. Click save
    ///6. Click Marketing List Members (left side)
    ///7. Click Manage Members
    ///8. Select "Use Lookup to add members" option and click OK
    ///9. In the lookup select the accounts to be added and click OK
    ///10. Save & close
    /// </summary>

    public class AddMembersToList : CrmWebTest
    {
        public void AddMembersToList_PreWebTest(object sender, PreWebTestEventArgs e)
        {
            EntityRequest er = new EntityRequest();
            er.Type = EntityNames.Users;
            er.ReturnAs = EntityNames.Users;
            er.ParentID = EntityManager.Instance.OrgId;

            System.Collections.Hashtable Props = new System.Collections.Hashtable();

            if (e.WebTest.Context.ContainsKey("UserRole"))
            {
                Props.Add("role", e.WebTest.Context["UserRole"]);
            }
            

            EntityRequest AccountEr = new EntityRequest();
            AccountEr.Type = EntityNames.Accounts;
            AccountEr.ParentID = Guid.NewGuid();
            AccountEr.ReturnAs = EntityNames.Accounts;

            Props.Add(EntityNames.Accounts, new EntityRequest[] { AccountEr });

            er.Props = Props;

            System.Collections.Hashtable Entities = EntityManager.Instance.GetEntities(er);

            user = (CRMEntity)Entities[EntityNames.Users];
            account = (CRMEntity)Entities[EntityNames.Accounts];

            e.WebTest.UserName = user["domainName"];
            e.WebTest.Password = user["userpassword"];
            
            crmServer = user["CrmServer"];
            tokenKey = EntityManager.Instance.ReadTokenKey(user["organizationid"]);

            orgId = new Guid(user["organizationid"]);            
        }

        public void AddMembersToList_PostWebTest(object sender, PostWebTestEventArgs e)
        {
            try
            {
                if (newListId != null)
                {
                    string newListString = newListId.ToString();
                    Guid g = EntityManager.Instance.GetOwnerGuid(new Guid(user[EntityIDNames.User]), new Guid(user["OrganizationId"]));
                    EntityManager.Instance.AddEntity(EntityNames.Lists, g, new string[] { "OwningUser", "ListID" , "EntityManagerOwningUser"}, new string[] { user["systemuserid"], newListString, g.ToString() });
                }
            }
            catch (System.FormatException fe)
            {
                System.Diagnostics.Trace.WriteLine("Failed to convert bogus data into Guid. " + fe.ToString());
            }
            finally
            {
                EntityManager.Instance.FreeEntity(user);
                EntityManager.Instance.FreeEntity(account);
            }
        }

        private void AddMembersToList_ValidateResponse(object sender, ValidationEventArgs e)
        {
            string ID = null;

            int idIdx = e.Response.BodyString.IndexOf(newIdMarker);
            ID = e.Response.BodyString.Substring(idIdx + (AddMembersToList.newIdMarker.Length), 36);
            try
            {
                ID = new Guid(ID).ToString();
            }
            catch (System.FormatException fe)
            {
                System.Diagnostics.Trace.WriteLine("Format exception: " + fe.ToString());
                e.IsValid = false;
                return;
            }
            e.IsValid = true;
        }

        public AddMembersToList()
        {
            WebRequest.RegisterPrefix("crm", new crmRequestFactory());
            refreshGridList = GridXmlHelper.ListPageViewRefresh(-1, myListViewId, null);

            this.Proxy = null;            
            PreWebTest += new EventHandler<PreWebTestEventArgs>(AddMembersToList_PreWebTest);
            PostWebTest += new EventHandler<PostWebTestEventArgs>(AddMembersToList_PostWebTest);
        }

        static AddMembersToList()
        {           
        }

        public override IEnumerator<WebTestRequest> GetRequestEnumerator()
        {
            this.BeginTransaction("NavListHomepage");

            _root_homepage_aspx hp = new _root_homepage_aspx(user);
            hp.etc = 4300;
            yield return (hp);

            this.EndTransaction("NavListHomepage");

            this.BeginTransaction("ManageMembersAdd");

            ma_lists_edit_aspx ma = new ma_lists_edit_aspx(user);
            yield return (ma);

            referer = ma.lastResponse.ResponseUri.AbsoluteUri;

            _forms_FormScript_js_aspx formScript = new _forms_FormScript_js_aspx(user);
            formScript.etc = 4300;
            formScript.FormType = "main";
            formScript.FormName = "crmForm";
            headerItem = new WebTestRequestHeader();
            headerItem.Name = "referer";
            headerItem.Value = referer;
            formScript.Headers.Add(headerItem);
            yield return (formScript);
            
            ma = new ma_lists_edit_aspx(user);
            ma.crmFormSubmitXml = EntityXmlHelper.GetCreateListXml(new Guid(user["systemuserid"]), 8);
            ma.crmFormSubmitMode = 1;
            ma.crmFormSubmitId = null;
            ma.crmFormSubmitObjectType = 4300;
            ma.crmFormSubmitSecurity = 852023;
            ma.crmFormUserModified = true;
            ma.crmFormSubmitOnline = 1;

            rpcInfo = Utils.GenerateWRPCToken(ma_lists_edit_aspx.url, user, tokenKey);
            ma.CRMWRPCToken = rpcInfo.token;
            ma.CRMWRPCTokenTimeStamp = rpcInfo.timeStamp;
            ma.ValidateResponse += this.AddMembersToList_ValidateResponse;

            yield return (ma);

            //get the newly created list id out of the post reply
            int idIdx = ma.lastResponse.BodyString.IndexOf(newIdMarker);
            string tempNewListId = ma.lastResponse.BodyString.Substring(idIdx + (AddMembersToList.newIdMarker.Length), 36);
            newListId = new Guid(tempNewListId);

            ma = new ma_lists_edit_aspx(user);
            ma.id = newListId;
            yield return (ma);

            referer = ma.lastResponse.ResponseUri.AbsoluteUri;

            AppGridWebService.AppGridWebService agws = new AppGridWebService.AppGridWebService();
            WebTestRequest wtrRefresh = null;
            try { agws.Refresh(refreshGridList); }
            catch (crmException x)
            {
                wtrRefresh = x.wtr;
                wtrRefresh.Url = Utils.ReplaceServerName(wtrRefresh.Url, user);

                string urlPath = wtrRefresh.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtrRefresh.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtrRefresh.Headers.Add(headerItem);
                wtrRefresh.Method = "Post";
            }
            yield return (wtrRefresh);

            formScript = new _forms_FormScript_js_aspx(user);
            formScript.etc = 4300;
            formScript.FormType = "main";
            formScript.FormName = "crmForm";
            headerItem = new WebTestRequestHeader();
            headerItem.Name = "referer";
            headerItem.Value = referer;
            formScript.Headers.Add(headerItem);
            yield return (formScript);
            
            ma_lists_areas_aspx listArea = new ma_lists_areas_aspx(user);
            listArea.oId = newListId;
            listArea.oType = 4300;
            listArea.security = 852023;
            listArea.createdfromcode = 1;
            listArea.tabSet = "areaListMember";
            yield return (listArea);

            MA_lists_ListQualificationDlg_dlg_manage_members_aspx listQualifications = new MA_lists_ListQualificationDlg_dlg_manage_members_aspx(user);
            yield return (listQualifications);

            MarketingAutomation.MarketingAutomationWebService maws = new MarketingAutomation.MarketingAutomationWebService();
            WebTestRequest wtrRetrieveList = null;
            string [] columns = new string[] {"createdfromcode"};
            try { maws.RetrieveList(newListId,columns); }
            catch (crmException x)
            {
                wtrRetrieveList = x.wtr;
                wtrRetrieveList.Url = Utils.ReplaceServerName(wtrRetrieveList.Url, user);

                urlPath = wtrRetrieveList.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtrRetrieveList.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtrRetrieveList.Headers.Add(headerItem);
                wtrRetrieveList.Method = "Post";
            }
            yield return (wtrRetrieveList);

            _controls_lookup_lookupmulti_aspx lookupMulti = new _controls_lookup_lookupmulti_aspx(user);
            lookupMulti.Class = "activityrelatedcustomer";
            lookupMulti.objecttypes ="1";
            lookupMulti.browse = 0;
            lookupMulti.ShowNewButton = 1;
            yield return (lookupMulti);

            _controls_lookup_lookupdata_aspx lookupData = new _controls_lookup_lookupdata_aspx(user);
            lookupData.ObjectType = 1;
            lookupData.Class = "activityrelatedcustomer";
            lookupData.objecttypes = "1";
            lookupData.browse = 0;
            lookupData.ShowNewButton = 1;
            lookupData.Mode = 4;
            lookupData.ColumnsOnly = 1;
            yield return (lookupData);

            lookupData = new _controls_lookup_lookupdata_aspx(user);
            lookupData.Class = "activityrelatedcustomer";
            lookupData.objecttypes = "1";
            lookupData.browse = 0;
            lookupData.ShowNewButton = 1;
            lookupData.Mode = 4;
            lookupData.ObjectType = 1;
            lookupData.searchvalue = Utils.GetRandomString(2, 2);
            yield return (lookupData);

            _grid_cmds_dlg_addtolist_aspx addToList = new _grid_cmds_dlg_addtolist_aspx(user);
            addToList.autoTrigger = 1;
            addToList.iObjType = 1;
            addToList.iTotal = 1;
            addToList.sIds = null;
            addToList.itemObjectId = newListId;
            yield return (addToList);

            addToList = new _grid_cmds_dlg_addtolist_aspx(user);
            addToList.iObjType = 1;
            addToList.iTotal = 1;
            addToList.iIndex = 0;
            addToList.itemObjectId = newListId;
            addToList.iId = new Guid(account[EntityIDNames.Account]);

            StringHttpBody httpBody = new StringHttpBody();
            httpBody.BodyString = "<node />";
            httpBody.ContentType = "text/xml";
            addToList.Body = httpBody;

            rpcInfo = Utils.GenerateWRPCToken(_grid_cmds_dlg_addtolist_aspx.url, user, tokenKey);

            headerItem = new WebTestRequestHeader();
            headerItem.Name = "CRMWRPCTokenTimeStamp";
            headerItem.Value = rpcInfo.timeStamp.ToString();
            addToList.Headers.Add(headerItem);
            headerItem = new WebTestRequestHeader();
            headerItem.Name = "CRMWRPCToken";
            headerItem.Value = rpcInfo.token;
            addToList.Headers.Add(headerItem);
            addToList.Method = "Post";

            yield return (addToList);

            maws = new MarketingAutomation.MarketingAutomationWebService();
            wtrRetrieveList = null;
            columns = new string[] { "membercount" };
            try { maws.RetrieveList(newListId, columns); }
            catch (crmException x)
            {
                wtrRetrieveList = x.wtr;
                wtrRetrieveList.Url = Utils.ReplaceServerName(wtrRetrieveList.Url, user);

                urlPath = wtrRetrieveList.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtrRetrieveList.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtrRetrieveList.Headers.Add(headerItem);
                wtrRetrieveList.Method = "Post";
            }
            yield return (wtrRetrieveList);

            // Make the list Grid for members
            tempNewListId = newListId.ToString();
            memberGrid = GridXmlHelper.MemberGridForListViewRefresh(-1, memberViewId, null, tempNewListId, "4300");
            agws = new AppGridWebService.AppGridWebService();
            wtrRefresh = null;
            try { agws.Refresh(memberGrid); }
            catch (crmException x)
            {
                wtrRefresh = x.wtr;
                wtrRefresh.Url = Utils.ReplaceServerName(wtrRefresh.Url, user);

                urlPath = wtrRefresh.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtrRefresh.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtrRefresh.Headers.Add(headerItem);
                wtrRefresh.Method = "Post";
            }
            yield return (wtrRefresh);

            this.EndTransaction("ManageMembersAdd");            
        }

        private const string newIdMarker = @"separator + ""id=";
        private CRMEntity user;
        private CRMEntity account;
        private string crmServer;
        private string tokenKey;
        private Guid newListId;
        private string refreshGridList;
        private string memberGrid;
        private string referer;

        private WebTestRequestHeader headerItem;
        private WRPCInfo rpcInfo;
        private string urlPath;

        private static string myListViewId = "823B9210-B82A-4B11-B0F6-B9E4C9C8403F";
        private static string memberViewId = "51DE84DD-732F-440F-A506-26123A19AB50";

        private Guid orgId;
    }
}
